package manong.serviceimpl;

import manong.beans.*;
import manong.constant.ServerResponse;
import manong.mapper.*;
import manong.service.IArrService;
import manong.util.DayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;


@Service
public class ArrServiceImpl implements IArrService {
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private ClassesMapper classesMapper;
    @Autowired
    private ClassroomMapper classroomMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private CourseTableMapper courseTableMapper;
    @Autowired
    private ArrangeMapper arrangeMapper;

    @Override
    public ServerResponse<String> arr(int weeks) {//weeks:20
        //查出所有 需要排课的课程安排 和 教室
        //todo 现在是全部查出来 条件后面可以修改

    	/*88888888888888888
    	将具体的分配课程的流程抽象到了handle方法里面
    	 88888888888888888*/
 
    	
        //需要排的课
        List<Arrange> arranges = arrangeMapper.selectByExample(new ArrangeQuery());
        /*88888888888888888
    	查询当前需要排的课
    	 88888888888888888*/
        
        
        
        //教室
        List<Classroom> classrooms = classroomMapper.selectByExample(new ClassroomQuery());
        /*88888888888888888
    	查询当前有多少教室
    	 88888888888888888*/
        
        
        List<CourseTable> tables = handle(arranges, classrooms);
        /*88888888888888888
     自己的理解：根据需要拍的课和教室放进抽取到的或着表示为封装的handle方法，handle方法根据这两个参数进行排课--》因为是随机排的课就需要一个明确的展示，周一到周五，不能出现周六周日的课，也要顺序来，不能一下周一一下周三一下周五
    	！！！！！此方法为核心方法，用于排课，排课成功放入tables，此时这是第一周的课，先排一周的，再在下面的大循环排1到20周的，排好再放到allTables的集合里--》批量插入
    	！！！！！！！！课只要没什么问题一般不会改
    	 88888888888888888*/
        
        
        List<CourseTable> allTables = new ArrayList<>();
        /*88888888888888888
    	存放所有已安排的课程
    	 88888888888888888*/
        
        
        
        
        /*88888888888888888
    进行过滤，从第一周到第weeks周，即第20周进行排课，顺序的将课程放入allTables的集合中
    ！！！！！！！从第一周到20周循环，讲课放入到数据库里面--》可以查第二周，第三周---》每周一样的
    	 88888888888888888*/
        for (int x = 1; x <= weeks; x++) {//每周的课是一样的
            for (CourseTable courseTable : tables) {
                if (courseTable.getTemporary() == 0) {
                    allTables.add(newCourseTable(courseTable,x));
                } else if (courseTable.getTemporary() == 1) {
                    if (x % 2 != 0) {
                        allTables.add(newCourseTable(courseTable,x));
                    }
                } else if (courseTable.getTemporary() == 2) {
                    if (x % 2 == 0) {
                        allTables.add(newCourseTable(courseTable,x));
                    }
                }
            }
        }
        
        
        courseTableMapper.deleteByExample(new CourseTableQuery());
        /*88888888888888888
       	删除之前有已排的课---》暂时成为空表
       	！！！！放好之后进行数据库的更新，   
       	 88888888888888888*/
           
        int count = courseTableMapper.batchInsert(allTables);
        /*88888888888888888
       	将实现好的课程插入到库，做持久化--》进行数据库课程的更新
       	！！！！！！！batch批量插入
       	 88888888888888888*/
           
        
        if (count > 0) {
            return ServerResponse.createBySuccess();
        }
        return ServerResponse.createByError();
        /*88888888888888888
       	判断是否插入成功，给出响应
       	 88888888888888888*/
           
    }

    private CourseTable newCourseTable(CourseTable c,Integer week){
        CourseTable courseTable = new CourseTable();
        courseTable.setArrId(c.getArrId());
        courseTable.setClassId(c.getClassId());
        courseTable.setRoomId(c.getRoomId());
        courseTable.setTecherId(c.getTecherId());
        courseTable.setCourseId(c.getCourseId());
        courseTable.setTimeId(c.getTimeId());
        courseTable.setTimeName(c.getTimeName());
        //todo
        courseTable.setSemeId(c.getSemeId());
        courseTable.setSemeName(c.getSemeName());

        courseTable.setClassName(c.getClassName());
        courseTable.setCourseName(c.getCourseName());
        courseTable.setRoomName(c.getRoomName());
        courseTable.setTecherName(c.getTecherName());
        courseTable.setTemporary(c.getTemporary());
        courseTable.setStatu(week);
        courseTable.setMark(c.getMark());
        return courseTable;


    }

    private List<CourseTable> handle(List<Arrange> arranges, List<Classroom> classrooms) {
        List<CourseTable> courseTables = new ArrayList<>();//存放课表
        ArrayList<ClassroomHelp> helps = new ArrayList<>();//存放教室
        for (Classroom c : classrooms) {  //第一层多少个教室
            for (int x = 1; x <= 5; x++) {  //第二层 周一到周五
                for (int y = 1; y <= 4; y++) {  //第三层 第一节课到第四节课
                    helps.add(toHelp(c, x, y));   //将循环放入到集合中--》选出空教室的时间
                }
            }
        }

        Random ra = new Random();  //随机函数--》随机选择--》自动排课
        int temp;        //存放临时值
        boolean isGo = true;  //判断是否添加成功

        for (Arrange arrange : arranges) {   //根据当前课程 28节
            Integer number = arrange.getStatu();   //分配状态--》可选
            //根据当前课程进行循环，为每个课程分配一个教室

            temp = ra.nextInt(helps.size() - 1);//获取随机值，周一到周五，5个教室，第一到第四节的哪一节课，选出一个nextint整数，eg 0-40 ，减一是从0开始，0为星期一第一个教室第一节

            
            //当前教室必定选出一个空教室
            for (int x = 0; x < helps.size(); x++) {//x<当前时间段空余教室（从周一到周五每天四节的教室）
                ClassroomHelp classroom = helps.get(temp);//根据随机数，eg：3->周一下午第三节
                if (classroom.getRoomSpace() >= number) {//number，看当前是否大于这个状态，当前的的课程的状态是否可以继续上，没有问题
                	//大于number，排课成功，添加到courseTable中并从helps中删除
                    courseTables.add(toTabel(arrange, classroom));
                    //排课成功，删除当前已被选择教室
                    helps.remove(x);//删除出去
                    isGo = true;//设置为true
                    break;//结束当前循环，进行下一次排课
                } else {
                    temp++;
                    if (isGo && temp == helps.size()) {//超过了随机数   174-181判断当前是否合法 当前是否有空余的教室，是否小于当前的课程
                        isGo = false;
                        temp = 0;
                    }//当前正常就排课，不正常就进行下一次循环
                    if (x == helps.size() - 1) {
                        isGo = true;
                        System.out.println(arrange.toString());
                    }
                }
            }
        }

        return courseTables;

    }

   private CourseTable toTabel(Arrange arrange, ClassroomHelp classroomHelp) {
        CourseTable courseTable = new CourseTable();
        courseTable.setArrId(arrange.getId());
        courseTable.setClassId(arrange.getClassId());
        courseTable.setRoomId(classroomHelp.getId());
        courseTable.setTecherId(arrange.getTecherId());
        courseTable.setCourseId(arrange.getCourseId());
        courseTable.setTimeId(classroomHelp.getNumber());
        courseTable.setTimeName(DayUtil.toDay(classroomHelp.getDay()));
        //todo
        courseTable.setSemeId(0);
        courseTable.setSemeName("第一学期");

        courseTable.setClassName(arrange.getClassName());
        courseTable.setCourseName(arrange.getCourseName());
        courseTable.setRoomName(classroomHelp.getRoomName());
        courseTable.setTecherName(arrange.getTecherName());
        courseTable.setTemporary(arrange.getSrd());
        courseTable.setStatu(0);
        courseTable.setMark("无");
        return courseTable;
    }

    private ClassroomHelp toHelp(Classroom classroom, Integer x, Integer y) {
        ClassroomHelp classroomHelp = new ClassroomHelp();
        classroomHelp.setId(classroom.getId());
        classroomHelp.setRoomName(classroom.getRoomName());
        classroomHelp.setRoomLayer(classroom.getRoomLayer());
        classroomHelp.setRoomSign(classroom.getRoomSign());
        classroomHelp.setRoomSpace(classroom.getRoomSpace());
        classroomHelp.setDay(x);
        classroomHelp.setNumber(y);
        classroomHelp.setStatu(classroom.getStatu());
        classroomHelp.setMark(classroom.getMark());
        return classroomHelp;
    }
}
//    //建立一个课表二维数组，其中20 = 5天*一天4节课，后续可以把这个参数提取出去
//    //CourseTable[][] courseTables = new CourseTable[20][classrooms.size()];
//    HashMap<Integer, HashMap<Integer, List<Classroom>>> classroom = new HashMap<>(5);
//    HashMap<Integer, List<Classroom>> day01 = new HashMap<>(4);
//    HashMap<Integer, List<Classroom>> day02 = new HashMap<>(4);
//    HashMap<Integer, List<Classroom>> day03 = new HashMap<>(4);
//    HashMap<Integer, List<Classroom>> day04 = new HashMap<>(4);
//    HashMap<Integer, List<Classroom>> day05 = new HashMap<>(4);
//
//        classroom.put(1, day01);
//                classroom.put(2, day02);
//                classroom.put(3, day03);
//                classroom.put(4, day04);
//                classroom.put(5, day05);
//
//                for (int i = 1; i <= 4; i++) {
//                day01.put(i, classrooms);
//                day02.put(i, classrooms);
//                day03.put(i, classrooms);
//                day04.put(i, classrooms);
//                day05.put(i, classrooms);
//                }